﻿#include "StdAfx.h"
#include "CameraSceneForAimingPoint.h"
#include "AimingPointManager.h"

#define FIRST_PERSON_WALK_CAMERA (_T("Camera0"))
#define CHARACTER_CONTROL_CAMERA (_T("Camera_char"))
#define FORWARD_FELLOW_CAMERA (_T("Camera_forward"))
#define LEFTSIDE_CAMERA (_T("Camera_left"))
#define PASS_BY_CAMERA (_T("Pass_by_camera"));
#define DEFAULT_CAMERA_SPEED 15.0f

#include "CameraOperations.h"

CCameraSceneForAimingPoint::CCameraSceneForAimingPoint(void)
{
	m_world = NULL;
	m_Running = FALSE;

	m_scene_state = SCENE_UNSTART;
	m_current_using_camera_name = FIRST_PERSON_WALK_CAMERA;
	m_waitingTimes = 0;
	
	m_pCamCharControl = NULL;
	m_pCamFirstPerson = NULL;

	m_walk_dir = VEC(0,0,1);
	m_face_dir = VEC(0,0,1);
}

CCameraSceneForAimingPoint::~CCameraSceneForAimingPoint(void)
{
	m_pCamCharControl = NULL;
	m_pCamFirstPerson = NULL;
}

void CCameraSceneForAimingPoint::on_world_created(CBaseWorld* pworld)
{
	m_world = pworld;
	m_pCamCharControl = NULL;
	m_pCamFirstPerson = NULL;
}

void CCameraSceneForAimingPoint::on_world_destroyed()
{
	//CAimingPointManager::deleteAllAimingPoint();
	m_world = NULL;
}

#include "AimingPointManager.h"
#include "AimingPoint.h"
#include "..\..\..\..\ThirdParty\tinyxml2_6_2\tinyxml.h"//2013.10.20 liyang 导入tinyxml库
void CCameraSceneForAimingPoint::on_save_project(CPakNode* scene_node, CSaveOpt* opt)
{
	//2014/1/13 liyang 开启console
	if(AllocConsole())
	{
		freopen("CONOUT$","w",stdout);
		printf("Start Using Console~\n");
	}

	CString project_filename = m_world->get_project_filename();//2014/1/13 liyang 获取打开的VRP文件名（有路径）
	//2014/1/13 liyang 根据filefun类提供的方法获得去掉路径后的VRP文件名
	CString vrpfilename = filefun::get_last_file_or_folder_name(project_filename);

	TiXmlDocument doc; 
	//TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "", ""); 
	//TiXmlElement * element = new TiXmlElement( "Hello" ); 
	//TiXmlText * text = new TiXmlText( "World" ); 
	//element->LinkEndChild( text ); 
	//doc.LinkEndChild( decl ); 
	//doc.LinkEndChild( element ); 
	CString savefilename = vrpfilename + _T(".xml");
	USES_CONVERSION;//2013/11/18 liyang 使用ATL宏w2a转化字符串
	LPSTR save_file_name = W2A(savefilename);

	//2014/1/13 liyang 保存场景中的摄像机的信息
	TiXmlElement* camNodes = new TiXmlElement("UserCameras");
	doc.LinkEndChild(camNodes);
	list<CCamObj> camlist = m_world->m_cam_scene->get_user_cams();
	list<CCamObj>::iterator iter = camlist.begin();
	for(iter;iter!=camlist.end();iter++)
	{
		TiXmlElement* camNode = new TiXmlElement("cameraNode");
		camNodes->LinkEndChild(camNode);

		camNode->SetAttribute("camType", (*iter)->get_cam_type());
		const char* camtypename = W2A( (*iter)->get_cam_type_name((*iter)->get_cam_type()) );
		camNode->SetAttribute("camTypeName", camtypename);
		const char* camName = W2A( (*iter)->get_name() );
		camNode->SetAttribute("camName", camName);
	}

	//2014/1/13 liyang 保存场景中的重点观察点的信息
	saveAimingPointXMLinfo(doc);

	doc.SaveFile(save_file_name); 
	printf("Stop Using Console~\n");
	//______________________________________________________________________  
	//2014/1/13 liyang 关闭console
	FreeConsole();
}

void CCameraSceneForAimingPoint::on_open_project(CPakNode* scene_node, const CTexPathInfo* tex_path_info)
{
	//2014/1/13 liyang 开启console
	if(AllocConsole())
	{
		freopen("CONOUT$","w",stdout);
		printf("Start Using Console~\n");
	}
	CString project_filename = m_world->get_project_filename();//2014/1/13 liyang 获取打开的VRP文件名（有路径）
	//2014/1/13 liyang 根据filefun类提供的方法获得去掉路径后的VRP文件名
	CString vrpfilename = filefun::get_last_file_or_folder_name(project_filename);
	vrpfilename += _T(".xml");
	USES_CONVERSION;//2013/11/18 liyang 使用ATL宏w2a转化字符串
	LPSTR load_file_name = W2A(vrpfilename);
	//2014/1/13 liyang 打开xml文件读取信息
	TiXmlDocument doc( load_file_name );
	bool loadok = doc.LoadFile();
	if(!loadok)
	{
		printf("openXMLFileError~\n");
		printf("Stop Using Console~\n");
		FreeConsole();
		return;
	}
	
	TiXmlElement* pAimingPointsElem=doc.FirstChildElement("AimingPoints"); 
	if(!pAimingPointsElem)
	{
		printf("noAimingPointsError~\n");
		printf("Stop Using Console~\n");
		FreeConsole();
		return;
	}

	loadAimingPointFromXML(doc);//从XML文件中读取AimingPoint的信息

	printf("Stop Using Console~\n");
	//______________________________________________________________________  
	//2014/1/13 liyang 关闭console
	FreeConsole();
}

void CCameraSceneForAimingPoint::init_3d_envment(CDevice* device)
{
	m_pdev = device->get_dev();	
}

void CCameraSceneForAimingPoint::render_in_view(CBaseVport* view, CRenderOption* opt)
{

	if(!m_Running)
	{
		CAimingPointManager::showAllAimingPointCamera(m_world,TRUE);
		CAimingPointManager::drawAllAimingPointCameraInfluenceRange(m_world);
		return;
	}
	//绘制AimingPoint的范围圈。当摄像机的eye进入范围圈之后，会根据AimingPoint的设计来操作相机
	//例如，当第一人称摄像机进入圈了之后，切换为跟随相机。
	CAimingPointManager::showAllAimingPointCamera(m_world,FALSE);

	SHORT push_shift = ::GetAsyncKeyState(VK_SHIFT);
	if(push_shift)//(!push_up && !push_down)
	{
		CAimingPointManager::drawAllAimingPointCameraInfluenceRange(m_world);
		CAimingPointManager::showAllAimingPointCamera(m_world,TRUE);
	}
}

void CCameraSceneForAimingPoint::frame_move(const CTimer* timer)
{
	if(!m_Running)
	{
		return;
	}
	frame_move_free_mode(timer);
}

//2014/1/15 liyang 自由控制模式下的摄像机影响逻辑
void CCameraSceneForAimingPoint::frame_move_free_mode(const CTimer* timer)
{
	if(!m_Running)
	{
		return;
	}

	if(!m_pCamCharControl || !m_pCamFirstPerson || !m_pCamForward || !m_pCamLeftSide)
	{
		return;
	}

	ISkeletonModel* pskVisitor = findSkeletonModelInScene(_T("visitor"));
	if(!pskVisitor)
	{
		return;
	}

	//2013/12/13 liyang 加入一个计时逻辑功能，当切换摄像机的时候，进入倒计时，倒计时结束后，才能继续操作
	if(m_scene_state == SCENE_WAITING)
	{
		m_move_ctrl = 0;
		double rapid_delta = timer->get_rapid_info(TRUE);//rapid_delta是每一帧的时间间隔
		m_waitingTimes -= rapid_delta;
		m_pCamCharControl->set_keyctrl_rot_speed(0.0f);
		m_pCamCharControl->set_keyctrl_speed(0.0f);
		//m_pCamCharControl->on_driven_data_changed();
		m_pCamFirstPerson->set_keyctrl_rot_speed(0.0f);
		m_pCamFirstPerson->set_keyctrl_speed(0.0f);
		//m_pCamFirstPerson->on_driven_data_changed();

		//2013/12/16 liyang 这里停止相机移动，以及设置相机的转动速度和移动速度为0都是为了等
		//相机完全切换完成之后才进行下一个动作。从而避免在边缘处相机反复出圈进圈所带来的bug
		m_world->execute_str_cmd(_T("相机移动控制, 2, -1"));//停止相机的移动。
		if(m_waitingTimes<=0)
		{
			m_pCamCharControl->set_keyctrl_rot_speed(1.0f);
			m_pCamCharControl->set_keyctrl_speed(DEFAULT_CAMERA_SPEED);
			//m_pCamCharControl->on_driven_data_changed();
			m_pCamFirstPerson->set_keyctrl_rot_speed(1.0f);
			m_pCamFirstPerson->set_keyctrl_speed(DEFAULT_CAMERA_SPEED);
			//m_pCamFirstPerson->on_driven_data_changed();
			//m_world->execute_str_cmd(_T("将相机聚焦到物体, 1, redbox"));
			CGuid uid = pskVisitor->get_id();
			m_pCamForward->set_rotater_target_id(uid);
			m_pCamCharControl->set_rotater_target_id(uid);

			m_scene_state = SCENE_NORMAL;
		}
		synchronizeCameraAndVisitor();
		return;
	}
	//2013/11/28 liyang 只有当第一次进入frame_move的时候，此if为真。
	//现在用来设置初始摄像机，这个工作无法在prepare_run完成
	else if(m_scene_state == SCENE_ENTER)
	{
		m_move_ctrl = 0;
		m_world->api_switch_cam_by_name(LEFTSIDE_CAMERA,TRUE);
		m_current_using_camera_name = LEFTSIDE_CAMERA;
		m_world->api_switch_cam_by_name(FORWARD_FELLOW_CAMERA,TRUE);
		m_current_using_camera_name = FORWARD_FELLOW_CAMERA;
		m_world->api_switch_cam_by_name(CHARACTER_CONTROL_CAMERA,TRUE);
		m_current_using_camera_name = CHARACTER_CONTROL_CAMERA;
		m_world->api_switch_cam_by_name(FIRST_PERSON_WALK_CAMERA,TRUE);
		m_current_using_camera_name = FIRST_PERSON_WALK_CAMERA;

		//2013/12/16 liyang 把角色控制相机移动到第一人称相机（行走相机）的位置
		VEC eye_pos = m_pCamFirstPerson->get_cam().get_eye_pos();
		VEC cam_movement = eye_pos - m_pCamCharControl->get_acc_move();
		cam_movement.y = 0;
		m_pCamCharControl->update_model_and_camtracker(NULL, 0.0f, cam_movement);
		m_pCamCharControl->set_acc_angle(0.0f);
		m_world->execute_str_cmd(_T("设置相机切换时间, 1000"));
		m_scene_state = SCENE_NORMAL;//场景运行模式
		return;
	}


	SHORT push_up = ::GetAsyncKeyState(VK_UP);
	SHORT push_down = ::GetAsyncKeyState(VK_DOWN);
/*
	SHORT push_w = ::GetAsyncKeyState(VK_W);
	if(push_w)
	{
		changeCameraForChar();
		pskVisitor->set_visible(TRUE);
	}
	SHORT push_s = ::GetAsyncKeyState(VK_S);
	if(push_s)
	{
		changeCameraForFirstPerson();
		pskVisitor->set_visible(FALSE);
	}

	SHORT push_shift = ::GetAsyncKeyState(VK_SHIFT);
	if(push_shift)
	{
		m_current_using_camera_name = LEFTSIDE_CAMERA;
		m_world->api_switch_cam_by_name(LEFTSIDE_CAMERA);
		
	}
	//synchronizeCameraAndVisitor();
	//return;
*/

	SHORT push_contrl = ::GetAsyncKeyState(VK_CONTROL);
	if(!push_contrl)//(!push_up && !push_down)
	{
		//CCamObj
		ICamObj* pcamera = findCameraInSceneByName( m_current_using_camera_name);
		if(!pcamera)
		{
			return;
		}
		//2013/12/1 liyang 注意这两种获得CCamera的区别
		//第一种只是获得了view,并不是获得camera_scene中的摄像机
		//第二种是通过camera_scene中的相机获得CCamera,应使用这一种
		//CCamera& cam = m_world->get_active_view()->get_camera();
		CCamera& cam = pcamera->get_cam();

		//2013/12/4 liyang 获取当前应该观察的AimingPoint
		CAimingPoint* pBestAimPoint = getBestAimingPointForFirstPersonCamera(); 

		//2013/12/4 liyang 如果使用的是Camera0相机,那么根据AimingPoint来引导镜头
		if( m_current_using_camera_name == FIRST_PERSON_WALK_CAMERA)
		{
			VEC eye = cam.get_eye_pos();
			VEC up = VEC(0,1,0);//2013/12/6 liyang 有AimingPoint的情况下，上方强制为（0,1,0）
			VEC target = cam.get_target_pos();
			target.y = eye.y;//2013/12/6 liyang 有AimingPoint的情况下，强制在Y方向上让用户去看AimingPoint
			
			bool ignoreAiming = false;//是否忽略重点观察，默认为不忽略
			//2014/1/15 liyang 增加判断逻辑，如果用户已经位于观察点影响范围内了，就不用观察观察点了
			if(pBestAimPoint && CAimingPointManager::checkCameraInAimingPointInfluenceRange(*pBestAimPoint, eye))
			{
				ignoreAiming = true;
			}
			//2014/1/15 liyang 如果有最佳观察点并且不忽略重点观察
			if(pBestAimPoint && !ignoreAiming)
			{
				VEC aimpoint = pBestAimPoint->getPosition();
				aimpoint.y = target.y;

				//pAimPoint->setObserveStyle(CAimingPoint::WIDE_ANGLE);
				int fov = cam.get_fov_in_degree();
				pcamera->get_cam().set_fov_in_degree( pBestAimPoint->getObserveStyleAngle());
				//pcamera->on_driven_data_changed();

				float alpha = pBestAimPoint->getAimingWeightValue();
				VEC aim_face = getNewAimDir(eye,target,aimpoint,alpha);
				cam.set_view_params(eye,eye+aim_face,up);
			}
			double rapid_delta = timer->get_rapid_info(TRUE);//rapid_delta是每一帧的时间间隔
			update_walk_dir_for_FirstCamera(rapid_delta);
		}
		else if(m_current_using_camera_name == CHARACTER_CONTROL_CAMERA)
		{
			double rapid_delta = timer->get_rapid_info(TRUE);//rapid_delta是每一帧的时间间隔
			update_walk_dir_for_Char_Control(rapid_delta);
		}
		else if(m_current_using_camera_name == FORWARD_FELLOW_CAMERA)
		{
			update_walk_dir();

			MAT visitor_mat = pskVisitor->get_other_wts();
			visitor_mat._41 += m_walk_dir.x;
			visitor_mat._42 += 0;
			visitor_mat._43 += m_walk_dir.z;
			pskVisitor->set_other_wts(visitor_mat);
			if(m_move_ctrl)
			{
				m_walk_dir.normalize_self();
				//float angle = asin(m_walk_dir.z/m_walk_dir.x);
				float angle = -atan2(m_walk_dir.z , m_walk_dir.x) - Pi/2;
				MAT rotMat;
				D3DXMatrixIdentity(&rotMat);
				D3DXMatrixRotationY(&rotMat,angle);
				pskVisitor->set_wts(m_scale_default_matrix * rotMat);
				//	m_pCamCharControl->update_model_and_camtracker(NULL, angle - m_pCamCharControl->get_acc_angle(), VEC(0,0,0));	
			}
		}
		else if(m_current_using_camera_name == LEFTSIDE_CAMERA)
		{
			//m_pCamLeftSide->update_model_and_camtracker(NULL, 0.0f, VEC(0,0,1));
			update_walk_dir2();
			if (m_move_ctrl&1) 
			{
				MAT visitor_mat = pskVisitor->get_other_wts();
				visitor_mat._41 += m_walk_dir.x;
				visitor_mat._42 += 0;
				visitor_mat._43 += m_walk_dir.z;
				pskVisitor->set_other_wts(visitor_mat);
			}
			if (m_move_ctrl&(1<<1))
			{
				m_pCamCharControl->update_model_and_camtracker(NULL, m_ag, VEC(0,0,0));
				//float angle = -atan2(m_walk_dir.z , m_walk_dir.x) - Pi/2;
				//m_pCamCharControl->update_model_and_camtracker(NULL,angle-m_pCamCharControl->get_real_acc_angle(), VEC(0,0,0));
			}
			if (m_move_ctrl&(1<<2))
			{
				m_pCamCharControl->update_model_and_camtracker(NULL, m_ag, VEC(0,0,0));
				//float angle = -atan2(m_walk_dir.z , m_walk_dir.x) - Pi/2;
				//m_pCamCharControl->update_model_and_camtracker(NULL,angle-m_pCamCharControl->get_acc_angle(), VEC(0,0,0));
			}
			if (m_move_ctrl&(1<<3))
			{
				MAT visitor_mat = pskVisitor->get_other_wts();
				visitor_mat._41 -= m_walk_dir.x;
				visitor_mat._42 -= 0;
				visitor_mat._43 -= m_walk_dir.z;
				pskVisitor->set_other_wts(visitor_mat);
			}
		}
		//2013/12/5 liyang 同步第一人称相机和游览者模型的数据
		synchronizeCameraAndVisitor();
		//2013/12/5 liyang 
		VEC firstPersonEyePos = m_pCamFirstPerson->get_cam().get_eye_pos();
		VEC testPoint(firstPersonEyePos.x,0,firstPersonEyePos.z);
		changeCameraForAimingPointRange(pBestAimPoint, testPoint);
	}
	else
	{
		//2013/12/5 liyang 同步第一人称相机和游览者模型的数据
		synchronizeCameraAndVisitor();
	}
}

void CCameraSceneForAimingPoint::prepare_run()
{
	m_Running = TRUE;

	m_scene_state = SCENE_ENTER;//进入场景模式
	m_waitingTimes = 0;//等待时间设置为0
	m_walk_dir = VEC(0,0,1);
	m_face_dir = VEC(0,0,1);
	m_move_ctrl = 0x0;

	//2013/12/5 liyang 记录下visitor模型的默认stw矩阵，并对这个矩阵的第四行进行调整
	{
		D3DXMatrixIdentity(&m_scale_default_matrix);

		ISkeletonModel* pskVisitor = NULL;
		list<IVrItem*> result;
		m_world->find_objs_by_name(_T("visitor"), CIntSet::gen(skeleton_scene),&result);
		if (result.size())
		{
			pskVisitor =(ISkeletonModel*)result.front();
		} 
		if(!pskVisitor)
		{
			return;
		}
		m_scale_default_matrix = pskVisitor->get_wts();
		m_scale_default_matrix._41 = 0;
		m_scale_default_matrix._42 = 0;
		m_scale_default_matrix._43 = 0;
		m_scale_default_matrix._44 = 1;
		//	MAT rotate_Mat;
		//	D3DXMatrixRotationY( &rotate_Mat, Pi);
		//	m_scale_default_matrix = m_scale_default_matrix *  rotate_Mat;
	}
	
	CCameraOperations::prepareCameraOperations(m_world);
	
	m_pCamCharControl = NULL;
	m_pCamFirstPerson = NULL;
	m_pCamForward     = NULL;
	m_pCamLeftSide    = NULL;
	ICamObj* pcam_leftside = findCameraInSceneByName(LEFTSIDE_CAMERA);
	if(pcam_leftside)
	{
		m_pCamLeftSide = pcam_leftside;
	}
	ICamObj* pcam_forward = findCameraInSceneByName(CHARACTER_CONTROL_CAMERA);
	if(pcam_forward)
	{
		m_pCamForward = pcam_forward;
	}
	ICamObj* pcam_char = findCameraInSceneByName(CHARACTER_CONTROL_CAMERA);
	if(pcam_char)
	{
		m_pCamCharControl = pcam_char;
	}
	//2013/11/28 liyang 设置初始的摄像机
	ICamObj* pcam = findCameraInSceneByName(FIRST_PERSON_WALK_CAMERA);
	if(pcam)
	{
		m_pCamFirstPerson = pcam;
		
	}
	m_current_using_camera_name = FIRST_PERSON_WALK_CAMERA;
}

void CCameraSceneForAimingPoint::after_run()
{
	m_Running = FALSE;
	m_scene_state = SCENE_EXIT;//退出场景模式
	m_waitingTimes = 0;
}

BOOL CCameraSceneForAimingPoint::pre_process_keyboard_message(UINT message, WPARAM wParam, LPARAM lParam)
{
	ISkeletonModel* pskVisitor = findSkeletonModelInScene(_T("visitor"));
	if(!pskVisitor)
	{
		return FALSE;
	}

	SHORT push_up = ::GetAsyncKeyState(VK_UP);
	SHORT push_down = ::GetAsyncKeyState(VK_DOWN);
/*	if (push_up||push_down)
	{
		//pskVisitor->clear_cycle_action(pskVisitor->get_default_cycle_action_name());
		pskVisitor->set_walk_cycle_action_name(pskVisitor->get_run_cycle_action_name());
		pskVisitor->play_cycle_action(pskVisitor->get_run_cycle_action_name());
	}
	else
	{
		pskVisitor->clear_cycle_action(pskVisitor->get_run_cycle_action_name());
		pskVisitor->play_cycle_action(pskVisitor->get_default_cycle_action_name());
	}
*/

	control_moveControl(message, wParam);
	control_moveControl2(message, wParam);
	return FALSE;
}


//2013/12/3 liyang 获得新的相机注释方向
//参数为eye的位置，当前的target位置，新的target位置，以及影响系数alpha
//alpha范围是0-1.0, alpha=1表示完全按照新的方向指引
VEC CCameraSceneForAimingPoint::getNewAimDir(VEC eye, VEC current_aim, VEC new_aim, float alpha)
{
	if(alpha<0.00001f||alpha>1.0f)
	{
		return VEC(1.0f,0.0f,0.0f);
	}
	VEC current_face = current_aim - eye;
	VEC new_face = new_aim - eye;
	VEC aim_face = current_face*(1-alpha) + new_face*alpha;
	return aim_face;
}

//2013/11/29 liyang 根据名字查找摄像机，找到了返回该相机指针，否则返回NULL
ICamObj* CCameraSceneForAimingPoint::findCameraInSceneByName(CString find_name)
{
	ICamObj* out_pcam = NULL;
	list<CCamObj> camlist = m_world->m_cam_scene->get_user_cams();
	list<CCamObj>::iterator iter = camlist.begin();
	for(iter;iter!=camlist.end();iter++){
		CString name = (*iter)->get_name();
		if(name == find_name)
		{
			out_pcam = (*iter);
			break;
		}
	}
	return out_pcam; 
}

#include "v3d\H\ModelScene.h"
#include "v3d\h\skeletonscene.h"
ISkeletonModel* CCameraSceneForAimingPoint::findSkeletonModelInScene(CString find_name)
{
	ISkeletonModel* out_skeleton = NULL;
	list<CSkeletonModel> skeletonList = m_world->m_skeleton_scene->get_models();
	//m_world->m_skeleton_scene->get_models();
	list<CSkeletonModel>::iterator iter = skeletonList.begin();
	for(iter;iter!=skeletonList.end();iter++)
	{
		CString name = (*iter)->get_name();
		if(name == find_name)
		{
			out_skeleton = *iter;
			break;
		}
	}
	return out_skeleton;
}

#include "v3d\H\ModelScene.h"
IVrItem* CCameraSceneForAimingPoint::getSceneObjectByName(CString name)
{
	IVrItem* obj = NULL;
	list<IVrItem*>* pList = m_world->m_model_scene->get_all_vr_objs();
	list<IVrItem*>::iterator iter = pList->begin();

	for(iter;iter!=pList->end();iter++){
		CString s = (*iter)->get_name();
		if(s == name){
			obj = *iter;
			break;
		}
	}
	return obj;
}

VEC& CCameraSceneForAimingPoint::getCameraEyePosition(CString cam_name)
{
	ICamObj* pcam = findCameraInSceneByName(cam_name);
	if(!pcam)
	{
		return VEC(0,0,0);
	}
	VEC camera_eye_pos = pcam->get_cam().get_eye_pos();

	//m_world->execute_str_cmd(_T("取相机位置, ")+cam_name);
	return camera_eye_pos;
}

//2013/12/5 liyang 切换为角色控制相机
void CCameraSceneForAimingPoint::changeCameraForChar()
{
	if(m_current_using_camera_name == CHARACTER_CONTROL_CAMERA)
	{
		return;
	}
	ISkeletonModel* pskVisitor = findSkeletonModelInScene(_T("visitor"));
	if(!pskVisitor)
	{
		return;
	}

	//进入切换相机的等待状态
	m_scene_state = SCENE_WAITING;
	m_waitingTimes = 1000;


	if(!m_pCamCharControl)
	{
		return;
	}
	if(!m_pCamFirstPerson)
	{
		return;
	}
	VEC eye_pos = m_pCamFirstPerson->get_cam().get_eye_pos();
	VEC cam0_dir =	m_pCamFirstPerson->get_cam().get_forward_dir(TRUE);
	cam0_dir.y = 0;
	//2013/12/6 liyang 计算希望让摄像机对准的方向的角度
	//这个角度是我们希望让角色控制相机所对准的角度。
	//注意，是对准到这个角度，而不是旋转这个角度。
	//2013/12/6 liyang 修改了角度计算公式，之前使用的cam0_dir.get_angle_in_radian(VEC(0,0,-1));有错误
	float angle = -atan2(cam0_dir.z , cam0_dir.x) - Pi/2;
	//2013/12/6 liyang 这个方法很重要，设置了角色控制相机所观察的模型的位移偏移和角度偏移
	//通过设置偏移，让观察的模型移动到想要移动到的位置。在这里就是第一人称相机的eye的位置
	VEC acc_move = m_pCamCharControl->get_acc_move();
	VEC cam_movement = eye_pos-acc_move;
	cam_movement.y = 0;
	float acc_angle = m_pCamCharControl->get_acc_angle();
	
	//2014/1/15 liyang 重新把visitor模型回归到初始位置
	m_pCamCharControl->update_model_and_camtracker(NULL, 0.0f - acc_angle, VEC(0.0f,0.0f,0.0f));
	m_pCamCharControl->set_acc_angle(0.0f);
	//2014/1/15 liyang 再旋转visitor模型到想要让它转到的角度
	m_pCamCharControl->update_model_and_camtracker(NULL, angle, cam_movement);
	m_pCamCharControl->set_acc_angle(angle);
	acc_angle = m_pCamCharControl->get_acc_angle();
	
	m_pCamCharControl->set_rotater_target_id(CGuid::s_gen_zero());
	//m_world->api_switch_cam_by_name(CHARACTER_CONTROL_CAMERA),TRUE);
	m_world->execute_str_cmd(_T("设置相机切换时间, 1000"));
	m_world->execute_str_cmd(_T("切换相机(通过名称), Camera_char, 1"));
	m_current_using_camera_name = CHARACTER_CONTROL_CAMERA;
}

void CCameraSceneForAimingPoint::changeCameraForForwardFollow()
{
	ISkeletonModel* pskVisitor = findSkeletonModelInScene(_T("visitor"));
	if(!pskVisitor)
	{
		return;
	}

	if(m_current_using_camera_name == FORWARD_FELLOW_CAMERA)
	{
		return;
	}
	//进入切换相机的等待状态
	m_scene_state = SCENE_WAITING;
	m_waitingTimes = 1000;//等待切换的时间


	if(!m_pCamCharControl)
	{
		return;
	}
	if(!m_pCamFirstPerson)
	{
		return;
	}

	VEC eye_pos = m_pCamFirstPerson->get_cam().get_eye_pos();
	//eye_pos.y = 0;
	VEC tar_pos = m_pCamFirstPerson->get_cam().get_target_pos();
	tar_pos.y = eye_pos.y;
	VEC cam0_dir = tar_pos - eye_pos;
	//2013/12/6 liyang 计算希望让摄像机对准的方向的角度
	//这个角度是我们希望让角色控制相机所对准的角度。
	//注意，是对准到这个角度，而不是旋转这个角度。
	//2013/12/6 liyang 修改了角度计算公式，之前使用的cam0_dir.get_angle_in_radian(VEC(0,0,-1));有错误
	float angle = -atan2(cam0_dir.z , cam0_dir.x) - Pi/2;
	VEC acc_move = m_pCamForward->get_acc_move();
	VEC cam_movement = eye_pos-acc_move;
	cam_movement.y = 0;
	float acc_angle = m_pCamForward->get_acc_angle();
	//2014/1/15 liyang 重新把visitor模型回归到初始位置
	m_pCamForward->update_model_and_camtracker(NULL, 0.0f - acc_angle, VEC(0.0f,0.0f,0.0f));
	m_pCamForward->set_acc_angle(0.0f);
	//2014/1/15 liyang 再旋转visitor模型到想要让它转到的角度
	m_pCamForward->update_model_and_camtracker(NULL, angle, cam_movement);
	m_pCamForward->set_acc_angle(angle);

/*
	m_pCamForward->set_rotater_target_id(CGuid::s_gen_zero());
	CGuid nowid = m_pCamForward->get_rotater_target_id();
	m_world->execute_str_cmd(_T("设置相机切换时间, 1000"));
	CCamera& assist_cam = m_pCamAssistFixed->get_cam();
	m_world->execute_str_cmd(_T("切换相机(通过名称), Camera_Assist, 1"));
*/
	//camobj->set_cam_back_radius(vis->get_box().get_transf(vis->get_final_wts()).get_radius() * 5 );

	m_pCamForward->set_rotater_target_id(CGuid::s_gen_zero());

	m_current_using_camera_name = FORWARD_FELLOW_CAMERA;
	m_world->execute_str_cmd(_T("设置相机切换时间, 1000"));
	//m_world->api_switch_cam_by_name(FORWARD_FELLOW_CAMERA);
	m_world->execute_str_cmd(_T("切换相机(通过名称), Camera_forward, 1"));
	m_world->execute_str_cmd(_T("设置相机切换时间, 1000"));
}

void CCameraSceneForAimingPoint::changeCameraForLeftSide()
{
	if(m_current_using_camera_name == LEFTSIDE_CAMERA)
	{
		return;
	}
	if(!m_pCamFirstPerson || !m_pCamLeftSide)
	{
		return;
	}
	//进入切换相机的等待状态
	m_scene_state = SCENE_WAITING;
	m_waitingTimes = 1000;//等待切换的时间
	
	CCamera& cam = m_pCamFirstPerson->get_cam();
	VEC eye = cam.get_eye_pos();
	VEC target = cam.get_target_pos();
	VEC dir = target - eye;
	dir.y = 0;

	float angle = -atan2(dir.z , dir.x) - Pi/2;
	VEC movement = eye - m_pCamCharControl->get_acc_move();
	movement.y = 0;
	m_pCamCharControl->update_model_and_camtracker(NULL, angle - m_pCamCharControl->get_real_acc_angle(), movement);
	m_world->execute_str_cmd(_T("设置相机切换时间, 1000"));
	m_current_using_camera_name = LEFTSIDE_CAMERA;
	m_world->api_switch_cam_by_name(LEFTSIDE_CAMERA);
	//m_world->execute_str_cmd(_T("切换相机(通过名称), Camera_char, 1"));
}

//2013/12/5 liyang 切换为第一人称相机
void CCameraSceneForAimingPoint::changeCameraForFirstPerson()
{
	if(m_current_using_camera_name == FIRST_PERSON_WALK_CAMERA)
	{
		return;
	}
	//进入切换相机的等待状态
	m_scene_state = SCENE_WAITING;
	m_waitingTimes = 1000;//等待切换的时间

	m_world->execute_str_cmd(_T("设置相机切换时间, 1000"));
	m_world->execute_str_cmd(_T("切换相机(通过名称), Camera0, 1"));
	m_current_using_camera_name = FIRST_PERSON_WALK_CAMERA;
}

//2013/12/5 liyang 为AimingPoint判断是否切换摄像机
//这个方法决定，当摄像机的eye进入了AimingPoint的影响范围内，
//即进入了该AimingPoint的m_radius_of_camera_change_influence内的时候，进行的摄像机切换
void CCameraSceneForAimingPoint::changeCameraForAimingPointRange(CAimingPoint* pAimPoint, VEC test_pos)
{
	if(!pAimPoint)
	{
		//如果没有摄像机的情况下，切换成第一人称相机
		if(m_current_using_camera_name != FIRST_PERSON_WALK_CAMERA)
		{
			changeCameraForFirstPerson();
		}
		return;
	}
	if(CAimingPointManager::checkCameraInAimingPointInfluenceRange(*pAimPoint, test_pos))
	{
		//在AimingPoint的影响范围内时，如果当前是第一人称相机，切换成角色控制相机
		switch(pAimPoint->m_camera_type)
		{
			case CAimingPoint::FIRST_PERSON_WALK:
				if(m_current_using_camera_name != FIRST_PERSON_WALK_CAMERA)
				{
					changeCameraForFirstPerson();
				}
				break;
			case CAimingPoint::FOLLOW_BEHIND_WALK:
				if(m_current_using_camera_name != CHARACTER_CONTROL_CAMERA)
				{
					changeCameraForChar();
				}
				break;
			case CAimingPoint::FOWARD_FOLLOW:
				if(m_current_using_camera_name != FORWARD_FELLOW_CAMERA)
				{
					changeCameraForForwardFollow();
				}
				break;
			case CAimingPoint::LEFT_SIDE:
				if(m_current_using_camera_name != LEFTSIDE_CAMERA)
				{
					changeCameraForLeftSide();
				}
				break;
			default:
				if(m_current_using_camera_name != FIRST_PERSON_WALK_CAMERA)
				{
					changeCameraForFirstPerson();
				}
				break;
		}
	}
	else
	{
		//不在AimingPoint的影响范围内时，如果是角色控制相机，切换成第一人称相机
		if(m_current_using_camera_name != FIRST_PERSON_WALK_CAMERA)
		{
			changeCameraForFirstPerson();
		}
	}

}

//2013/12/5 liyang 同步第一人称相机和Visitor模型的信息
//FirstPerson相机（行走相机）模式下，把visitor的模型移动到摄像机的eye位置
//角色控制相机模式下，把行走相机移动到visitor模型的位置。
void CCameraSceneForAimingPoint::synchronizeCameraAndVisitor()
{
	if(!m_pCamCharControl || !m_pCamFirstPerson)
	{
		return;
	}

	ISkeletonModel* pskVisitor = findSkeletonModelInScene(_T("visitor"));
	if(!pskVisitor)
	{
		return;
	}
	

	//FirstPerson相机（行走相机）模式下，把visitor的模型移动到摄像机的eye位置
	if(m_current_using_camera_name == FIRST_PERSON_WALK_CAMERA)
	{
		CCamera& cam = m_pCamFirstPerson->get_cam();
		//2013/12/6 liyang 这里只是设置了pskVisitor的位置(通过set_other_wts)
		//事实上，当切换到角色控制相机的时候，
		//通过update_model_and_camtracker来设置pskVisitor骨骼模型的位移偏移和角度偏移就可以了
		//这里还调整了一下pskVisitor的wts矩阵的几个参数，不调整好像会有问题。
		MAT rotate;			
		D3DXMatrixIdentity(&rotate);
		VEC froward = cam.get_forward_dir(TRUE);
		MAT stw_matrix = pskVisitor->get_wts();
		stw_matrix._41 = 0; stw_matrix._42 = 0; stw_matrix._43 = 0; stw_matrix._44 = 1;
		pskVisitor->set_wts(stw_matrix);
		pskVisitor->set_visible(TRUE);

		MAT old_transformMatrix = pskVisitor->get_other_wts();
		VEC new_eye = cam.get_eye_pos();
		MAT transformMatrix;
		D3DXMatrixIdentity(&transformMatrix);
		transformMatrix._41 = new_eye.x;
		transformMatrix._42 = old_transformMatrix._42;
		transformMatrix._43 = new_eye.z;
		pskVisitor->set_other_wts(transformMatrix);

		//2014/1/15 liyang 面向的方向就是第一人称摄像机的方向
		m_face_dir = froward;
		m_visitor_dir = froward;
	/*
		MAT final_mat = pskVisitor->get_final_wts();
		ICamObj* pcam_char = findCameraInSceneByName(CHARACTER_CONTROL_CAMERA);
		if(!pcam_char)
		{
			return;
		}
		pcam_char->adjust_tracker_camera_by_obj_pos();
		pcam_char->on_driven_data_changed();*/
	}
	//角色控制相机模式下，把行走相机移动到visitor模型的位置。
	else if(m_current_using_camera_name == CHARACTER_CONTROL_CAMERA)
	{
		CCamera& first_cam = m_pCamFirstPerson->get_cam();
		//得到第一人称相机（行走相机）应该设置的位置，即pskVisitor的位置
		VEC first_cam_eye = first_cam.get_eye_pos();
		MAT other_mat = pskVisitor->get_other_wts();
		VEC eye = VEC(other_mat._41, first_cam_eye.y, other_mat._43);
		//得到第一人称相机（行走相机）应该设置的视线方向，即Camera_char的正前方。
		VEC up = VEC(0,1,0);
		VEC forward = m_pCamCharControl->get_cam().get_forward_dir(true);
		forward.y = 0;
		first_cam.set_view_params(eye, eye+forward, up);//设置第一人称相机（行走相机）的参数
		pskVisitor->set_visible(TRUE);

/*		同步朝向
		forward.normalize_self();
		m_face_dir = forward;
		float acc_angle = -m_pCamCharControl->get_acc_angle() - Pi/2;
		VEC visitor_dir(cos(acc_angle), 0.0f, sin(acc_angle));
		visitor_dir.normalize_self();
		m_visitor_dir = visitor_dir;*/
	}
	else if(m_current_using_camera_name == FORWARD_FELLOW_CAMERA)
	{
		CCamera& cam = m_pCamFirstPerson->get_cam();
		//得到第一人称相机（行走相机）应该设置的位置，即pskVisitor的位置
		VEC cam_eye = cam.get_eye_pos();
		MAT other_mat = pskVisitor->get_other_wts();
		VEC eye = VEC(other_mat._41, cam_eye.y, other_mat._43);
		//得到第一人称相机（行走相机）应该设置的视线方向，即Camera_char的正前方。
		VEC up = VEC(0,1,0);
		VEC froward = m_walk_dir;
		froward.x += 0.00001;
		//VEC froward = m_pCamForward->get_cam().get_forward_dir(true);
		froward.y = 0;
		cam.set_view_params(eye, eye+froward, up);//设置第一人称相机（行走相机）的参数
		pskVisitor->set_visible(TRUE);
	}
	else if(m_current_using_camera_name == LEFTSIDE_CAMERA)
	{
		CCamera& cam = m_pCamFirstPerson->get_cam();
		//得到第一人称相机（行走相机）应该设置的位置，即pskVisitor的位置
		VEC cam_eye = cam.get_eye_pos();
		VEC old_dir = cam.get_target_pos() - cam_eye;
		MAT other_mat = pskVisitor->get_other_wts();
		VEC eye = VEC(other_mat._41, cam_eye.y, other_mat._43);
		if(m_walk_dir.x!=0 && m_walk_dir.z!=0)
		{
			VEC up = VEC(0,1,0);
			VEC froward = m_walk_dir;
			froward.x += 0.00001;
			froward.y = 0;
			cam.set_view_params(eye, eye+froward, up);//设置第一人称相机（行走相机）的参数
		}

		pskVisitor->set_visible(TRUE);
	}
}

//2013/12/5 liyang 以第一人称相机为基准，获得最佳的AimingPoint
CAimingPoint* CCameraSceneForAimingPoint::getBestAimingPointForFirstPersonCamera()
{
	ICamObj* pcamera = findCameraInSceneByName( FIRST_PERSON_WALK_CAMERA );
	if(!pcamera)
	{
		return NULL;
	}
	//2013/12/1 liyang 注意这两种获得CCamera的区别
	//第一种只是获得了view,并不是获得camera_scene中的摄像机
	//第二种是通过camera_scene中的相机获得CCamera,应使用这一种
	//CCamera& cam = m_world->get_active_view()->get_camera();
	CCamera& cam = pcamera->get_cam();
	VEC current_face_dir = cam.get_forward_dir(TRUE);

	//VEC cam_pos = getCameraPosition(FIRST_PERSON_WALK_CAMERA);
	VEC eye = cam.get_eye_pos();
	VEC up = cam.get_up_vec(TRUE);
	VEC target = cam.get_target_pos();

	CAimingPoint* pAimPoint = NULL; 
	//2013/12/4 liyang 查找合适的AimingPoint，如果找到了，根据该AimingPoint来进行操作
	if(m_current_using_camera_name == FIRST_PERSON_WALK_CAMERA)
	{
		pAimPoint = CAimingPointManager::getSuitableAimingPointForFirstPersonCamera(m_world,eye,target);
	}
	else if(m_current_using_camera_name == CHARACTER_CONTROL_CAMERA)
	{
		pAimPoint = CAimingPointManager::getSuitableAimingPointForCharacterCamera(m_world,eye,target);
	}
	else if(m_current_using_camera_name == FORWARD_FELLOW_CAMERA)
	{
		//2014/1/1 liyang 当使用Forward_Follow相机的时候，跟CHARACTER_CONTROL_CAMERA的判断方法一样。
		pAimPoint = CAimingPointManager::getSuitableAimingPointForCharacterCamera(m_world,eye,target);
	}
	else if(m_current_using_camera_name == LEFTSIDE_CAMERA)
	{
		//2014/1/2 liyang 当使用Left_Side相机的时候，跟CHARACTER_CONTROL_CAMERA的判断方法一样。
		pAimPoint = CAimingPointManager::getSuitableAimingPointForCharacterCamera(m_world,eye,target);
	}
	return pAimPoint;
}

/*
//2013.9.13 应该是控制播放角色动画
void CProjectScene::update_action()
{
	if (m_sk)
	{
		if (m_move_ctrl)
		{
			m_sk->clear_cycle_action(m_sk->get_default_cycle_action_name());
			m_sk->play_cycle_action(m_sk->get_run_cycle_action_name());
		} else
		{
			m_sk->clear_cycle_action(m_sk->get_run_cycle_action_name());
			m_sk->play_cycle_action(m_sk->get_default_cycle_action_name());
		}
	}
}
*/

//2013.9.13 liyang 为了提高可读性,剥离摄像机运动方向键盘控制
BOOL CCameraSceneForAimingPoint::control_moveControl2(UINT message, WPARAM wParam)
{
	if (!m_Running)
	{
		return FALSE;
	}
	//2013.9.13 liyang 用一个这样的结构来控制方向运动：
	//一个四位的数字，从低位到高位，设置为0或1，分别控制前W，左A，右D，后S
	//如果最低位为1，例如0001，那么摄像机运动方向是前。如果是0010，那么向左运动。
	if (wParam==VK_UP)
	{
		if (message==WM_KEYDOWN)
		{
			m_move_ctrl|=1;
		} 
		else if (message==WM_KEYUP)
		{
			m_move_ctrl&=~1;
		}
	}
	else if (wParam==VK_LEFT)
	{
		if (message==WM_KEYDOWN)
		{
			m_move_ctrl|=(1<<1);
		}
		else if (message==WM_KEYUP)
		{
			m_move_ctrl&=~(1<<1);
		}
	}
	else if (wParam==VK_RIGHT)
	{
		if (message==WM_KEYDOWN)
		{
			m_move_ctrl|=(1<<2);
		}
		else if (message==WM_KEYUP)
		{
			m_move_ctrl&=~(1<<2);
		}
	}
	else if (wParam==VK_DOWN)
	{
		if (message==WM_KEYDOWN)
		{
			m_move_ctrl|=(1<<3);
		}
		else if (message==WM_KEYUP)
		{
			m_move_ctrl&=~(1<<3);
		}
	}
	else 
	{
		return FALSE;
	}
	//update_action();
	return TRUE;
}

BOOL CCameraSceneForAimingPoint::control_moveControl(UINT message, WPARAM wParam)
{
	if (!m_Running)
	{
		return FALSE;
	}
	//2013.9.13 liyang 用一个这样的结构来控制方向运动：
	//一个四位的数字，从低位到高位，设置为0或1，分别控制前W，左A，右D，后S
	//如果最低位为1，例如0001，那么摄像机运动方向是前。如果是0010，那么向左运动。
	if (wParam==VK_W)
	{
		if (message==WM_KEYDOWN)
		{
			m_move_ctrl|=1;
		} 
		else if (message==WM_KEYUP)
		{
			m_move_ctrl&=~1;
		}
	}
	else if (wParam==VK_A)
	{
		if (message==WM_KEYDOWN)
		{
			m_move_ctrl|=(1<<1);
		}
		else if (message==WM_KEYUP)
		{
			m_move_ctrl&=~(1<<1);
		}
	}
	else if (wParam==VK_D)
	{
		if (message==WM_KEYDOWN)
		{
			m_move_ctrl|=(1<<2);
		}
		else if (message==WM_KEYUP)
		{
			m_move_ctrl&=~(1<<2);
		}
	}
	else if (wParam==VK_S)
	{
		if (message==WM_KEYDOWN)
		{
			m_move_ctrl|=(1<<3);
		}
		else if (message==WM_KEYUP)
		{
			m_move_ctrl&=~(1<<3);
		}
	}
	else 
	{
		return FALSE;
	}
	//update_action();
	return TRUE;
}

//2014/1/15 liyang 第一人称相机使用的WASD控制
void CCameraSceneForAimingPoint::update_walk_dir_for_FirstCamera(float delta_time)
{
	VEC move_dir=VEC(0,0,0);
	//2013.9.13 liyang 采用四位二进制数控制方向。
	//从低位到高位分别控制 前W，左A，右D，后S
	if (m_move_ctrl&1) 
	{
		move_dir+=VEC(0,0,1);
	}
	if (m_move_ctrl&(1<<1))
	{
		move_dir+=VEC(-1,0,0);
	}
	if (m_move_ctrl&(1<<2))
	{
		move_dir+=VEC(1,0,0);
	}
	if (m_move_ctrl&(1<<3))
	{
		move_dir+=VEC(0,0,-1);
	}
	move_dir.normalize_self();

	CCamera& first_cam = m_pCamFirstPerson->get_cam();
	VEC target = first_cam.get_target_pos();
	VEC eye = first_cam.get_eye_pos();
	VEC dir = eye - target;
	VEC wdir = -dir;
	wdir.y=0;
	wdir.normalize_self();
	VEC camera_face_dir = wdir;
	camera_face_dir.normalize_self();
	VEC left_dir = camera_face_dir.cross(VEC(0,1,0));
	m_walk_dir = camera_face_dir*move_dir.z - left_dir*move_dir.x;
	
	//根据时间计算合适的摄像机运动向量
	float cam_speed = m_pCamFirstPerson->get_keyctrl_speed();
	cam_speed = cam_speed*delta_time/1000.0f;
	VEC cam_movement( m_walk_dir.x*cam_speed, 0.0f, m_walk_dir.z*cam_speed);

	VEC new_eye = eye + cam_movement;
	VEC new_target = target + m_walk_dir;
	first_cam.set_view_params(new_eye, new_target, VEC(0,1,0));
}

//2014/1/15 liyang 角色控制相机使用的WASD控制
void CCameraSceneForAimingPoint::update_walk_dir_for_Char_Control2(float delta_time)
{
	VEC move_dir=VEC(0,0,0);
	float rotate_angle = 0.0f;
	//2013.9.13 liyang 采用四位二进制数控制方向。
	//从低位到高位分别控制 前W，左A，右D，后S
	if (m_move_ctrl&1) 
	{
		move_dir+=VEC(0,0,1);
	}
	if (m_move_ctrl&(1<<1))
	{
		//move_dir+=VEC(-1,0,0);
		rotate_angle = -m_pCamCharControl->get_keyctrl_rot_speed()*delta_time/1000.0f;
	}
	if (m_move_ctrl&(1<<2))
	{
		//move_dir+=VEC(1,0,0);
		rotate_angle = m_pCamCharControl->get_keyctrl_rot_speed()*delta_time/1000.0f;
	}
	if (m_move_ctrl&(1<<3))
	{
		move_dir+=VEC(0,0,-1);
		rotate_angle = Pi;
	}
	move_dir.normalize_self();

	CCamera& first_cam = m_pCamCharControl->get_cam();
	VEC target = first_cam.get_target_pos();
	VEC eye = first_cam.get_eye_pos();
	VEC dir = eye - target;
	VEC wdir = -dir;
	wdir.y=0;
	wdir.normalize_self();
	VEC camera_face_dir = wdir;
	camera_face_dir.normalize_self();
	VEC left_dir = camera_face_dir.cross(VEC(0,1,0));
	m_walk_dir = camera_face_dir*move_dir.z - left_dir*move_dir.x;
	
	//根据时间计算合适的摄像机运动向量
	float cam_speed = m_pCamCharControl->get_keyctrl_speed();
	cam_speed = cam_speed*delta_time/1000.0f;
	VEC cam_movement( m_walk_dir.x*cam_speed, 0.0f, m_walk_dir.z*cam_speed);
	
	//重新设置跟踪模型（即visitor）的旋转角度和位移
	m_pCamCharControl->update_model_and_camtracker(NULL, rotate_angle, cam_movement);
	VEC new_movement = m_pCamCharControl->get_acc_move() + cam_movement;
	m_pCamCharControl->set_acc_move(new_movement);
	float new_angle = rotate_angle + m_pCamCharControl->get_acc_angle();
	m_pCamCharControl->set_acc_angle(new_angle);

/*
	if(m_move_ctrl)
	{
		float angle = -atan2(cam_movement.z, cam_movement.x) - Pi/2;
		float acc_angle = m_pCamCharControl->get_acc_angle();
		m_pCamCharControl->update_model_and_camtracker(NULL, -acc_angle, VEC(0,0,0));
		m_pCamCharControl->set_acc_angle(0.0f);
		m_pCamCharControl->update_model_and_camtracker(NULL, angle, VEC(0,0,0));
		m_pCamCharControl->set_acc_angle(angle);
	}
*/
}

//2014/1/15 liyang 角色控制相机使用的WASD控制
void CCameraSceneForAimingPoint::update_walk_dir_for_Char_Control(float delta_time)
{
	ISkeletonModel* pskVisitor = findSkeletonModelInScene(_T("visitor"));
	if(!pskVisitor)
	{
		return;
	}

	VEC move_dir=VEC(0,0,0);
	float rotate_angle = 0.0f;
	//2013.9.13 liyang 采用四位二进制数控制方向。
	//从低位到高位分别控制 前W，左A，右D，后S
	if (m_move_ctrl&1) 
	{
		move_dir+=VEC(0,0,1);
	}
	if (m_move_ctrl&(1<<1))
	{
		rotate_angle = -m_pCamCharControl->get_keyctrl_rot_speed()*delta_time/1000.0f;
	}
	if (m_move_ctrl&(1<<2))
	{
		rotate_angle = m_pCamCharControl->get_keyctrl_rot_speed()*delta_time/1000.0f;
	}
	if (m_move_ctrl&(1<<3))
	{
		move_dir+=VEC(0,0,-1);
		rotate_angle = Pi;
	}
	move_dir.normalize_self();

	CCamera& char_cam = m_pCamCharControl->get_cam();
	VEC target = char_cam.get_target_pos();
	VEC eye = char_cam.get_eye_pos();
	VEC dir = eye - target;
	VEC wdir = -dir;
	wdir.y=0;
	wdir.normalize_self();
	VEC camera_face_dir = wdir;
	camera_face_dir.normalize_self();
	VEC left_dir = camera_face_dir.cross(VEC(0,1,0));
	m_walk_dir = camera_face_dir*move_dir.z - left_dir*move_dir.x;
	
	//根据时间计算合适的摄像机运动向量
	float cam_speed = m_pCamCharControl->get_keyctrl_speed();
	cam_speed = cam_speed*delta_time/1000.0f;
	VEC cam_movement( m_walk_dir.x*cam_speed, 0.0f, m_walk_dir.z*cam_speed);
	//2014/1/15 liyang 因为update_model_and_camtracker的控制是针对局部坐标系的，所以只要移动cam_movement就是相对于模型的前方进行位移
	m_pCamCharControl->update_model_and_camtracker(NULL, 0.0f, cam_movement);

	if (m_move_ctrl&(1<<0))
	{
		float current_angle = -atan2(camera_face_dir.z, camera_face_dir.x) - Pi/2;
		current_angle += Pi;
		MAT rot_mat;
		D3DXMatrixRotationY(&rot_mat, current_angle);
		pskVisitor->set_wts(m_scale_default_matrix*rot_mat);
	}
	else if (m_move_ctrl&(1<<3))
	{
		float current_angle = -atan2(camera_face_dir.z, camera_face_dir.x) - Pi/2;
		current_angle += 0;
		MAT rot_mat;
		D3DXMatrixRotationY(&rot_mat, current_angle);
		pskVisitor->set_wts(m_scale_default_matrix*rot_mat);
	}

	if (m_move_ctrl&(1<<1) || m_move_ctrl&(1<<2))
	{
		float dot = camera_face_dir.x*m_walk_dir.x + camera_face_dir.y*m_walk_dir.y + camera_face_dir.z*m_walk_dir.z;
		if(dot>=0)
		{
			//重新设置跟踪模型（即visitor）的旋转角度和位移
			m_pCamCharControl->update_model_and_camtracker(NULL, rotate_angle, VEC(0,0,0));
			float new_angle = rotate_angle + m_pCamCharControl->get_acc_angle();
			m_pCamCharControl->set_acc_angle(new_angle);
		}
		else
		{
			//重新设置跟踪模型（即visitor）的旋转角度和位移
			m_pCamCharControl->update_model_and_camtracker(NULL, -rotate_angle, VEC(0,0,0));
			float new_angle = -rotate_angle + m_pCamCharControl->get_acc_angle();
			m_pCamCharControl->set_acc_angle(new_angle);
		}		
	}	

}


//2013.9.13 liyang 计算摄像机方向和速度的函数
void CCameraSceneForAimingPoint::update_walk_dir()
{
	m_ag=0;
	m_walk_dir=VEC(0,0,0);
	//2013.9.13 liyang 采用四位二进制数控制方向。
	//从低位到高位分别控制 前W，左A，右D，后S
	if (m_move_ctrl&1) 
	{
		m_walk_dir+=VEC(0,0,1);
	}
	if (m_move_ctrl&(1<<1))
	{
		m_walk_dir+=VEC(-1,0,0);
		if (m_move_ctrl&1)
		{
			m_ag+=D3DX_PI/4.0f;
		} else
		{
			m_ag+=D3DX_PI/2.0f;
		}
	}
	if (m_move_ctrl&(1<<2))
	{
		m_walk_dir+=VEC(1,0,0);
		if (m_move_ctrl&1)
		{
			m_ag-=D3DX_PI/4.0f;
		} else
		{
			m_ag-=D3DX_PI/2.0f;
		}
	}
	if (m_move_ctrl&(1<<3))
	{
		m_walk_dir+=VEC(0,0,-1);
		m_ag=D3DX_PI-(m_ag/2);
		//ag=D3DX_PI;
	}
	m_walk_dir.normalize_self();

	CCamera& cam = m_world->get_active_view()->get_cur_cam_obj()->get_cam();
	VEC target = cam.get_target_pos();
	VEC eye = cam.get_eye_pos();
	VEC dir = eye - target;
	VEC wdir = -dir;
	wdir.y=0;
	wdir.normalize_self();
	VEC camera_face_dir = wdir;
	camera_face_dir.normalize_self();
	VEC left_dir = camera_face_dir.cross(VEC(0,1,0));
	m_walk_dir = camera_face_dir*m_walk_dir.z - left_dir*m_walk_dir.x;
	//m_face_dir = camera_face_dir;
	//2013/11/9 liyang 到这里为止，就计算得到了相对于屏幕的正确的行走方向m_walk_dir

}

void CCameraSceneForAimingPoint::update_walk_dir2()
{
	m_ag=0;
	m_walk_dir=VEC(0,0,0);
	//2013.9.13 liyang 采用四位二进制数控制方向。
	//从低位到高位分别控制 前W，左A，右D，后S
	if (m_move_ctrl&1) 
	{
		m_walk_dir+=VEC(0,0,1);
	}
	if (m_move_ctrl&(1<<1))
	{
		m_walk_dir+=VEC(-1,0,0);
		m_ag -= Pi/24;
	}
	if (m_move_ctrl&(1<<2))
	{
		m_walk_dir+=VEC(1,0,0);
		m_ag += Pi/24;
	}
	if (m_move_ctrl&(1<<3))
	{
		m_walk_dir+=VEC(0,0,-1);
	}
	m_walk_dir.normalize_self();

	CCamera& cam = m_pCamFirstPerson->get_cam();
	VEC target = cam.get_target_pos();
	VEC eye = cam.get_eye_pos();
	VEC new_dir = target - eye;
	new_dir.y = 0;
	new_dir.normalize_self();
	//[x, y] x [-sinA cosA] = [x*cosA-y*sinA  x*sinA+y*cosA]
	VEC steer(cos(-m_ag),0,sin(-m_ag));
	m_walk_dir.x = new_dir.x*steer.x - new_dir.z*steer.z;
	m_walk_dir.z = new_dir.x*steer.z + new_dir.z*steer.x;
	m_walk_dir.normalize_self();
}

//2014/1/13 liyang 保存场景中的重点观察点的信息
void CCameraSceneForAimingPoint::saveAimingPointXMLinfo(TiXmlDocument& doc)
{
	USES_CONVERSION;//使用ATL宏w2a转化字符串
	TiXmlElement* aimPointsNode = new TiXmlElement("AimingPoints");
	doc.LinkEndChild(aimPointsNode);

	vector<CAimingPoint> aim_point_vector = CAimingPointManager::m_vector_AimingPoint;
	vector<CAimingPoint>::iterator iter;
	int amount = aim_point_vector.size();
	aimPointsNode->SetDoubleAttribute("amount",amount);
	for(iter = aim_point_vector.begin(); iter!=aim_point_vector.end(); iter++)
	{
		CString point_name = iter->m_point_name;
		TiXmlElement* newAimPointNode = new TiXmlElement("AimingPoint");
		aimPointsNode->LinkEndChild(newAimPointNode);

		LPSTR str_out = W2A(point_name);
		TiXmlText* aim_text = new TiXmlText(str_out);
		newAimPointNode->LinkEndChild(aim_text);

		str_out = W2A(iter->m_point_name);
		newAimPointNode->SetAttribute("Name",str_out);
		//	newAimPointNode->SetAttribute("Style",iter->m_observe_style);
		//	newAimPointNode->SetAttribute("CameraType",iter->m_camera_type);
		//	newAimPointNode->SetDoubleAttribute("InfluenceRange",iter->m_radius_of_camera_change_influence);
		//	newAimPointNode->SetDoubleAttribute("ObserveWeight", iter->m_aiming_weight);

		TiXmlElement* positionNode = new TiXmlElement("Position");
		newAimPointNode->LinkEndChild(positionNode);
		VEC pos = iter->getPosition();
		positionNode->SetDoubleAttribute("x",pos.x);
		positionNode->SetDoubleAttribute("y",pos.y);
		positionNode->SetDoubleAttribute("z",pos.z);

		//2014/1/13 liyang 输出拍摄风格（摄像机的fov）
		TiXmlElement* styleNode = new TiXmlElement("Style");
		newAimPointNode->LinkEndChild(styleNode);
		styleNode->SetAttribute("Style",iter->m_observe_style);

		//2014/1/13 liyang 输出摄像机类型
		TiXmlElement* cameratypeNode = new TiXmlElement("CameraType");
		newAimPointNode->LinkEndChild(cameratypeNode);
		CString type_name = iter->getCameraSwitchType(iter->m_camera_type);
		str_out = W2A(type_name);
		cameratypeNode->SetAttribute("CameraTypeName", str_out);
		cameratypeNode->SetAttribute("CameraTypeValue",iter->m_camera_type);

		//2014/1/13 liyang 输出影响范围
		TiXmlElement* rangeNode = new TiXmlElement("InfluenceRange");
		newAimPointNode->LinkEndChild(rangeNode);
		rangeNode->SetDoubleAttribute("InfluenceRange",iter->m_radius_of_camera_change_influence);

		//2014/1/13 liyang 输出权重
		TiXmlElement* weightNode = new TiXmlElement("ObserveWeight");
		newAimPointNode->LinkEndChild(weightNode);
		CString weight_name = iter->getAimingWeightName(iter->m_aiming_weight);
		str_out = W2A(weight_name);
		weightNode->SetAttribute("ObserveWeightName", str_out);
		weightNode->SetDoubleAttribute("ObserveWeightIndex", iter->m_aiming_weight);
	}	
}

//2014/1/14 liyang 从XML文件中读取AimingPoint的信息
void CCameraSceneForAimingPoint::loadAimingPointFromXML(TiXmlDocument& doc)
{
	TiXmlElement* pRootElement = doc.FirstChildElement();
	TiXmlElement* aimingPointsNode = NULL;
	aimingPointsNode = getNodeAndSibsBehindByName(pRootElement, _T("AimingPoints"));

	if(!aimingPointsNode)
	{
		printf("there is no aiming points node.\n");
		return;
	}

	TiXmlElement* aimingPointElement = aimingPointsNode->FirstChildElement();
	while(aimingPointElement)
	{
		TiXmlAttribute* pNameAttrib= aimingPointElement->FirstAttribute();
		CString point_name = CString(pNameAttrib->Value());//获得当前AimingPoint的名字
		getInfoForEveryAimingPoint(point_name, aimingPointElement);
		aimingPointElement = aimingPointElement->NextSiblingElement();
	}

	/*
	TiXmlElement* aimingPointsNode2 = NULL;
	aimingPointsNode2 = getNodeInChildrenByName(aimingPointsNode, _T("Position"));
	if(!aimingPointsNode2) 
	{
		printf("there is no aiming points node.\n");
		return;
	}

	TiXmlAttribute* pAttrib= aimingPointsNode->FirstAttribute();
	TiXmlAttribute* pAttrib2= aimingPointsNode2->FirstAttribute();


	printf(aimingPointsNode2->Value());
	*/
}

//2014/1/13 liyang 在当前节点以及其之后的兄弟节点中查找指定的节点
TiXmlElement* CCameraSceneForAimingPoint::getNodeAndSibsBehindByName(TiXmlElement* pElementCheck, CString findNodeValue)
{
	TiXmlElement* pFirstElement = pElementCheck;
	TiXmlElement* aimingPointsNode = NULL;
	while(pFirstElement)
	{
		CString node_name(pFirstElement->Value());
		if(node_name == findNodeValue)
		{
			aimingPointsNode = pFirstElement;
			break;
		}
		else
		{
			pFirstElement = pFirstElement->NextSiblingElement();
		}
	}
	return aimingPointsNode;
}

//2014/1/13 liyang 在给定节点以及其子节点中查找指定的节点
TiXmlElement* CCameraSceneForAimingPoint::getNodeInChildrenByName(TiXmlElement* pElementCheck, CString findNodeValue)
{
	TiXmlElement* aimingPointsNode = NULL;
	//2014/1/13 liyang 先检测传入的节点自身
	{
		CString node_name(pElementCheck->Value());
		if(node_name == findNodeValue)
		{
			aimingPointsNode = pElementCheck;
			return aimingPointsNode;
		}
	}
	//检测传入的节点的所有子节点
	TiXmlElement* pFirstElement = pElementCheck->FirstChildElement();
	while(pFirstElement)
	{
		CString node_name(pFirstElement->Value());
		if(node_name == findNodeValue)
		{
			aimingPointsNode = pFirstElement;
			break;
		}
		else
		{
			//在子节点里递归查找
			TiXmlElement* nodeInSublins = getNodeInChildrenByName(pElementCheck->FirstChildElement(), findNodeValue);
			if(nodeInSublins)
			{
				aimingPointsNode = nodeInSublins;
				break;
			}
			pFirstElement = pFirstElement->NextSiblingElement();
		}
	}
	return aimingPointsNode;
}

//2014/1/14 liyang 根据属性名在当前Element中查找
TiXmlAttribute* CCameraSceneForAimingPoint::getAttributeInNodeByName(TiXmlElement* pElementCheck, CString findAttributeName)
{
	TiXmlAttribute* pAttrib = NULL; 
	pAttrib = pElementCheck->FirstAttribute();
	while(pAttrib)
	{
		if(findAttributeName == CString(pAttrib->Name()))
		{
			return pAttrib;
		}
		pAttrib = pAttrib->Next();
	}
	return NULL;
}

//2014/1/14 liyang 从xml中读取每一个AimingPoint的信息，如位置，拍摄风格，摄像机类型等
void CCameraSceneForAimingPoint::getInfoForEveryAimingPoint(CString point_name, TiXmlElement* aimingPointElement)
{
	printf("Aimingpoint输出开始：\n");	

	//2014/1/14 liyang 得到当前点的position属性
	VEC point_position(0,0,0);
	{
		TiXmlElement* positionElement = getNodeInChildrenByName(aimingPointElement, _T("Position"));
		double pos_x = 0.0, pos_y=0.0, pos_z = 0.0;
		TiXmlAttribute* pfindAttrib = getAttributeInNodeByName(positionElement, _T("x"));
		if (pfindAttrib->QueryDoubleValue(&pos_x)==TIXML_SUCCESS)
		{
			printf("x: %f.3 \n",pos_x);	
		}
		pfindAttrib = getAttributeInNodeByName(positionElement, _T("y"));
		if (pfindAttrib->QueryDoubleValue(&pos_y)==TIXML_SUCCESS)
		{
			printf("y: %f.3 \n",pos_y);	
		}
		pfindAttrib = getAttributeInNodeByName(positionElement, _T("z"));
		if (pfindAttrib->QueryDoubleValue(&pos_z)==TIXML_SUCCESS)
		{
			printf("z: %f.3 \n",pos_z);	
		}
		point_position = VEC(pos_x,pos_y,pos_z);
	}

	//2014/1/14 liyang 获得style属性
	int style_index = 0;
	{
		TiXmlElement* styleElement = getNodeInChildrenByName(aimingPointElement, _T("Style"));
		TiXmlAttribute* pfindAttrib = getAttributeInNodeByName(styleElement, _T("Style"));
		if (pfindAttrib->QueryIntValue(&style_index)==TIXML_SUCCESS)
		{
			printf("style_index：%d \n",style_index);	
		}
	}

	//2014/1/14 liyang 获得摄相机类型
	int cameratype_index = 0;
	{
		TiXmlElement* camtypeElement = getNodeInChildrenByName(aimingPointElement, _T("CameraType"));
		TiXmlAttribute* pfindAttrib = getAttributeInNodeByName(camtypeElement, _T("CameraTypeValue"));
		if (pfindAttrib->QueryIntValue(&cameratype_index)==TIXML_SUCCESS)
		{
			printf("cameratype_index：%d \n",cameratype_index);
		}
	}

	//2014/1/14 liyang 观察点的影响范围
	double influenceRange = 1.0f;
	{
		TiXmlElement* influenceRangeElement = getNodeInChildrenByName(aimingPointElement, _T("InfluenceRange"));
		TiXmlAttribute* pfindAttrib = getAttributeInNodeByName(influenceRangeElement, _T("InfluenceRange"));
		if (pfindAttrib->QueryDoubleValue(&influenceRange)==TIXML_SUCCESS)
		{
			printf("influenceRange：%f.3 \n",influenceRange);
		}
	}

	//2014/1/14 liyang 获得观察权重
	int observeWeightIndex = 0;
	{
		TiXmlElement* observeWeightElement = getNodeInChildrenByName(aimingPointElement, _T("ObserveWeight"));
		TiXmlAttribute* pfindAttrib = getAttributeInNodeByName(observeWeightElement, _T("ObserveWeightIndex"));
		if (pfindAttrib->QueryIntValue(&observeWeightIndex)==TIXML_SUCCESS)
		{
			printf("observeWeightIndex：%d \n",observeWeightIndex);
		}
	}

	CAimingPointManager::createAimingPointForLoadingXML(point_name,
											point_position, 
											(CAimingPoint::OBSERVE_STYLE)style_index,
														influenceRange,
											(CAimingPoint::CAMERA_TYPE)cameratype_index,
											(CAimingPoint::AIMING_WEIGHT)observeWeightIndex);

	printf("Aimingpoint输出结束！\n");
}

